Challenge #4: Date Parsing 〜文章から様々な日付形式のデータを抽出してフォーマットを揃える〜 – Alteryx Weekly Challenge
Alteryxでは、ワークフロー作成スキルを磨く手段の1つとして『Weekly Challenge』という取り組みがAlteryx Community内で展開されています。Weekly Challengeの詳細については下記をご参照ください。
先日Alteryxチーム内の会話でこの『Weekly Challenge』の話が挙がり、シリーズを新設して皆でやってみようか(成果をブログにアウトプットしてみようか)と始めてみたところ、中々に良い滑り出し(2日で計3本)です。
ちなみにこの『Weekly Challenge』、同じお題でも解き方は人に拠って千差万別。『こういう解き方もあるのか...』と他の人の内容を見ることでワークフロー作成の新たな勉強にもなるのです。なので今後は当ブログでも『同じお題を別の方法で解いた』というエントリが出てくるかもしれません。
という事で、私もこの流れに乗ってしまおうと思います。
当エントリでチャレンジするお題は『#4:Date Parsing』です。
#4:問題内容
『#4:Date Parsing』の問題エントリは以下となります。
そして問題はこちら。
入力ファイルとして用意されているのはField_1という1列のみ。中身は任意の文章となっています。この中に、幾つかの書式バリエーション(提示されているのは以下4パターン)で出力済となっている日付形式の文字列が含まれており、
- 16-APR-2005
- Nov 16, 1900
- 4-SEP-00
- Jan 5 2000
その内容を抽出して同じフォーマットでの日付データに揃えましょう、というものです。
解答例の解説
実際に解いてみた内容をワークフローにまとめたものが以下となります。
当問題の肝となるのは『いかにして日付の情報を抜き出し、変換するか』という部分です。
ワークフローを作成する前に、まずはじめに取り組んだのは『幾つかある日付パターンを抽出する正規表現を準備する』部分です。以下の情報源などを参考にしつつ、
- よく使う正規表現はもうググりたくない!
- 正規表現の基本
- 正規表現サンプル(日付を検索する)
- 正規表現サンプル(桁数を範囲指定して数字を検索する)
- Regex to match month name followed by year - Stack Overflow
こちらの正規表現デバッガーサイトを使い、意図した条件でマッチさせられるかどうかを確認。
条件を一通りカバーするために用意した正規表現の一覧が以下となります。個人的にはそこまで正規表現に精通している訳では無いので『おい、もっとスマートなものがあるだろう』というツッコミもあるかもしれませんがそこは御容赦頂ければと思います。m(_ _)m
\d{2}-[A-Za-z]{3}-\d{4} \d{1}-[A-Za-z]{3}-\d{2} [A-Za-z]{3} \d{2}, \d{4} \d{2}-[A-Za-z]{3}-\d{2} \d{2}-[A-Za-z]{4,9}-\d{4} [A-Za-z]{3,9} \d{1,2} \d{4}
『日付の情報を抜き出す』部分については『RegEx Tool』を用いました。
『上記条件のいずれかに合致すればその値を抜き出す』としたかったので、上記条件群をOR条件で繋げる形とし、以下の設定値を生成。
(\d{2}-[A-Za-z]{3}-\d{4}|\d{1}-[A-Za-z]{3}-\d{2}|[A-Za-z]{3} \d{2}, \d{4}|\d{2}-[A-Za-z]{3}-\d{2}|\d{2}-[A-Za-z]{4,9}-\d{4}|[A-Za-z]{3,9} \d{1,2} \d{4})
パースする対象項目を選び、上記正規表現文字列をRegular Expression欄に設定。Output Methodを『Parse』としてOutputフィールド名も微調整を加えて設定完了です。
次の『Formula Tool』ではそれぞれ抜き出せた日付情報文字列を条件に応じた形で一律日付データに変換しました。まぁこの辺ももうちょっとエレガントな方法があるような気もしていますが(ベタな方法で御容赦ください)...
IF REGEX_Match([RegExOutPut],"\d{2}-[A-Za-z]{3}-\d{4}") THEN DateTimeParse([RegExOutPut],"%d-%b-%Y") ELSEIF REGEX_Match([RegExOutPut],"\d{1}-[A-Za-z]{3}-\d{2}") THEN DateTimeParse([RegExOutPut],"%d-%b-%y") ELSEIF REGEX_Match([RegExOutPut],"[A-Za-z]{3} \d{2}, \d{4}") THEN DateTimeParse([RegExOutPut],"%b %d, %y") ELSEIF REGEX_Match([RegExOutPut],"\d{2}-[A-Za-z]{3}-\d{2}") THEN DateTimeParse([RegExOutPut],"%d-%b-%y") ELSEIF REGEX_Match([RegExOutPut],"\d{2}-[A-Za-z]{4,9}-\d{4}") THEN DateTimeParse([RegExOutPut],"%d-%B-%y") ELSEIF REGEX_Match([RegExOutPut], "[A-Za-z]{3,9} \d{1,2} \d{4}") THEN DateTimeParse([RegExOutPut],"%b %d %Y") ELSE "" ENDIF
文字列から日付情報に変換する部分はDateTimeParse関数を使い、所定のフォーマットを指定する事で対応しています。
そして最後は抽出直後のカラムを選択対象外とする事で列情報としても出力に合わせる形に。
一番最後は『出力例』と『ワークフローで作成した出力内容』が一致している事を確認するために、CREW Macroの『Expect Equal』ツールを使いました。
まとめ
という訳でAlteryx Weekly Challenge 『#4: Date Parsing 〜文章から様々な日付形式のデータを抽出してフォーマットを揃える〜』にチャレンジしてみた内容のご紹介でした。データとして準備した段階でこういった日付やタイムスタンプの情報は揃えておいて欲しいものですが、中々そう上手く行くものでも無いですよね...。そんな時にはこのエントリの内容を思い出して頂き、何らの情報をお役に立てて頂ければ幸いです。
Alteryxの導入なら、クラスメソッドにおまかせください
日本初のAlteryxビジネスパートナーであるクラスメソッドが、Alteryxの導入から活用方法までサポートします。14日間の無料トライアルも実施中ですので、お気軽にご相談ください。